package it.omnisong.server.index;

import it.omnisong.client.model.Wikilink;
import it.omnisong.server.persistence.postgres.PostgresException;
import it.omnisong.server.persistence.dao.WikipediaDAO;
import it.omnisong.server.retrieval.AstraWebDataSource;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.store.LockObtainFailedException;
import org.apache.lucene.util.Version;
import org.junit.Test;

public class WikipediaIndexer {
	
	private FSDirectory dir;
	private IndexWriter writer;
	private List<Wikilink> queue = new ArrayList<Wikilink>();
	private Analyzer analyzer;
	private String indexDir = "war/omnisonggwt/index/wikipedia";
	
	public WikipediaIndexer() throws IOException {
	    this.dir = FSDirectory.open(new File(this.indexDir));
	    this.analyzer = new StandardAnalyzer(Version.LUCENE_30);
	}

	/* indicizza tutti i link di wikipedia presenti nel database */
	public void indexWikilinksInDB() throws PostgresException, IOException {
	    
		/* mi crea un nuovo indice o sovrascrive quello esistente */
	    this.writer = new IndexWriter(this.dir, this.analyzer,
	    							  true, IndexWriter.MaxFieldLength.LIMITED); 
	    
	    retrieveWikilinksFromDB(); // recupero tutti i record dalla tabella wikilink e li metto in this.queue
	    
	    String name = null;
	    String url = null;
	    String id = null;
	    
	    int originalNumDocs = this.writer.numDocs();
	    for (Wikilink l : this.queue) {
	    	try {
	    		name = l.getName();
	    		url = l.getUrl();
	    		id = l.getId();
	    		Document doc = new Document();
	    		doc.add(new Field("url", url, 
	    					Field.Store.YES,
	    	                Field.Index.NO));
	    		doc.add(new Field("name", name,
	    	                Field.Store.YES,
	    	                Field.Index.ANALYZED));
	    		doc.add(new Field("id", id,
    	                	Field.Store.YES,
    	                	Field.Index.NO));
	    		this.writer.addDocument(doc);
	    		System.out.println("Added: " + url);
	    	}
	    	catch (Exception e) {
	    		System.out.println("Could not add: " + url);
	    	}
	    }
	    
	    int newNumDocs = this.writer.numDocs();
	    System.out.println("");
	    System.out.println("************************");
	    System.out.println((newNumDocs - originalNumDocs) + " links added.");
	    System.out.println("************************");
	    this.closeWriter();
	    this.queue.clear();
	 }
	
	/* metodo che aggiunge un wikilink all'indice */
	public void addWikilinkToIndex(Wikilink wl) throws IOException {
		
		this.writer = new IndexWriter(this.dir, this.analyzer,
				  false, IndexWriter.MaxFieldLength.LIMITED); 
		
		try {
    		Document doc = new Document();
    		doc.add(new Field("url", wl.getUrl(), 
    					Field.Store.YES,
    	                Field.Index.NO));
    		doc.add(new Field("name", wl.getName(),
    	                Field.Store.YES,
    	                Field.Index.ANALYZED));
    		doc.add(new Field("id", wl.getId(),
	                	Field.Store.YES,
	                	Field.Index.NO));
    		this.writer.addDocument(doc);
    		System.out.println("Added: " + wl.getUrl());
    	}
    	catch (Exception e) {
    		System.out.println("Could not add: " + wl.getUrl());
    	}
		
	}
	
	/* recupera tutti il link di wikipedia inseriti nel database */
	private void retrieveWikilinksFromDB() throws PostgresException {
	    
		WikipediaDAO wikiDAO = new WikipediaDAO();
		
		try {
			this.queue = wikiDAO.retrieveAll();
		}
		catch(PostgresException e) {
			throw e;
		}
	}
	
	/* chiude l'indice */
	public void closeWriter() throws IOException {
	    this.writer.optimize();
	    this.writer.close();
	}
	
	/* test di indicizzazione */
	@Test
	public void index() {
		try {
			indexWikilinksInDB();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}
